/*
 *  key_handler.c
 *  pire2pireV1
 *
 *  Created by jihed kamkoum on 04/05/10.
 *  Copyright 2010 ENSEIRB. All rights reserved.
 *
 */

#include "key_handler.h"

return_t handler_KeyEvents(const char * events,SOCKET* sock,char * IP_S,int * PORT_S,int semid,Liste * listeClients,int fdpipe0,int fdpipe1){
	
	char message[NAMESIZE];
	//char * parametre;
	//recuperation du nom du message
	sscanf(events, "%s", message);
	if (strcmp(message, "connect") == 0) {
		// message de la form connect ip port
		char name[NAMESIZE],ip[NAMESIZE];
		int port;
		sscanf(events,"%s %s : %d",name,ip,&port);
		connect_program(ip,port,sock);
		return RT_OK;
	} else if (strcmp(message, "list") == 0) {
		return RT_OK;
	} else if (strcmp(message, "set") == 0) {
		// message de la forme set option = valeur
		//close(fdpipe0);
		if((write(fdpipe1, events, (strlen(events)+1))==-1)){
			perror("write");
			exit(EXIT_FAILURE);
		}
		return RT_OK;
	} else if (strcmp(message, "checksum") == 0) {
		return RT_OK;
	} else if (strcmp(message, "get") == 0) {
		get(sock,events);
		
		return RT_OK;
	} else if (strcmp(message, "info") == 0) {
		return RT_OK;
	} else if (strcmp(message, "neighbourhood") == 0) {
		neighbourhood(sock,events,semid);
		return RT_OK;
	}
	fprintf(stderr,"message non reconnu\n");
	return RT_ERR;
}
void neighbourhood(int * sock,const char * message,int semid){
	if(*sock!=-1){
		sock_puts(*sock, message);
		int arg[2];
		struct sembuf op;
		op.sem_num = 0; //Test si le thread est dispo
		op.sem_op = -1; //P()
		op.sem_flg = 0; //attente de l'operation
		if((semop(semid, &op, 1)==0)){
			/*thread disponnible*/
			pthread_t threadneighbourhood;
			/*creation du thread*/
			arg[0] = *sock;
			arg[1]= semid;
			if((pthread_create(&threadneighbourhood, NULL,(void *)f_thread_neighbourhood,arg))==-1)
				printf("probleme pthread_create \n");
			else {
				changer_ordo_priorite(threadneighbourhood, SCHED_RR, 5);
			}
		}
		else{
			perror("semop P()");
		}		
	}
	else {
		printf("No connection done !\n");
	}
	
}
void * f_thread_neighbourhood(int * args){
	printf("debut thread %d\n",pthread_self());
	//retarder l'execution du thread pour que la priorite soit effective
	sleep(rand()%3);
	int semid= args[1];
	char buffer[NAMESIZE];
	char recived[BUFSIZ];
	memset((char *) &buffer, 0, sizeof(buffer));
	memset((char *) &recived, 0, sizeof(recived));
	int ret;
	int i=0;
	if((ret=recv(args[0], buffer, sizeof(buffer), 0))==-1)
		perror("receive");
	else if(ret !=0){
		if(atoi(buffer)){
			i=atoi(buffer)-1 ;
			while (1) {
				if((ret=recv(args[0], recived, sizeof(recived), 0))==-1)
					perror("receive");
				else if (ret !=0) {
					printf("%s\n",recived);
					i--;
					if (i==0) {
						//plus rien a resevoir
						break;
					}
					sched_yield();
					sleep(1);
				}
			}
		}
		else {
			printf("problem neighbourhood\n");
		}
		
		
	}
	/*Liberation d'un thread client*/
	struct sembuf op;
	op.sem_num = 0; //Test si le thread est dispo
	op.sem_op = 1; //V()
	op.sem_flg = 0; //aucune importance
	if((semop(semid, &op, 1)==-1)){
		perror("semop V()");
	}
	printf("fin thread %d\n",pthread_self());
	pthread_exit(NULL);
	
}

void get(int * sock,const char * message){
	if(*sock!=-1){
		sock_puts(*sock, message);
		
	}
	else {
		printf("No connection done !\n");
	}
	
}

int connect_program(const char * ip,int port,int * sock ){
	if(*sock!=-1){
		close(*sock);
	}
	ssize_t ret;
	int csock;
	SOCKADDR_IN sin;
	bzero((char*)&sin, sizeof(SOCKADDR_IN));
	char buffer[BUFSIZ] = "";
	/*creation de la socket*/
	*sock = socket(AF_INET, SOCK_STREAM, 0);
	/* Configuration de la connexion */
	sin.sin_addr.s_addr = inet_addr(ip);
	sin.sin_family = AF_INET;
	sin.sin_port = htons(port);
	/* essai de connection*/
	if((csock=connect(*sock, (SOCKADDR*)&sin, sizeof(sin))) != SOCKET_ERROR){
		printf("Connexion à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
		
		if((ret=recv(*sock, buffer, sizeof(buffer), 0))==-1)
			perror("receive");
		else
			printf("Chaine recus : %s\n", buffer);
		//		if ((ret = send(*sock, buffer,sizeof(buffer),0))==-1) {
		//			perror("send");
		//		}
		//		else {
		//			printf("Chaine envoyer : %s\n", buffer);
		//		}
		
	}
	else {
		printf("Connexion impossible à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
	}
	
	return 0;
}
